<template>
    <tool-header>
        {{ title }}
    </tool-header>
    <a-form :label-col="labelCol" :wrapper-col="wrapperCol">
        <a-form-item label="Encrypt Type">
            <a-segmented v-model:value="modelRef.encryptType" :options="data" />
        </a-form-item>
        <a-form-item label="Passphrase" name="passphrase">
            <a-input-password v-model:value="modelRef.passphrase" placeholder="input passphrase" />
        </a-form-item>
        <a-form-item label="Mode" name="mode">
            <a-select v-model:value="modelRef.mode" style="width: 200px" :options="modeOptions"></a-select>
        </a-form-item>
        <a-form-item label="Padding" name="padding">
            <a-select v-model:value="modelRef.padding" style="width: 200px" :options="paddingOptions"></a-select>
        </a-form-item>
        <!-- <a-form-item label="Key Size" name="keySize">
            <a-select v-model:value="modelRef.keySize" style="width: 200px" :options="keySizeOptions"></a-select>
        </a-form-item> -->
        <a-form-item label="Input" v-bind="validateInfos.base64Input">
            <a-textarea v-model:value="modelRef.base64Input" :rows="4" />
        </a-form-item>
        <a-form-item label="Output">
            <a-textarea v-model:value="base64Output" :rows="4" />
        </a-form-item>
    </a-form>
</template>
<script lang="ts" setup>
import { reactive, ref, computed } from 'vue';
import { Form } from 'ant-design-vue';
import type { SelectProps } from 'ant-design-vue';
import { useRoute } from 'vue-router'
import ToolHeader from '../ToolHeader.vue'
import CryptoES from 'crypto-es';
import * as forge from 'node-forge'

const useForm = Form.useForm;
const route = useRoute();
const title = route.query.title

const modeOptions = ref<SelectProps['options']>([
    { value: 'CBC', label: 'CBC' },
    { value: 'CFB', label: 'CFB' },
    { value: 'CTR', label: 'CTR' },
    { value: 'OFB', label: 'OFB' },
    { value: 'ECB', label: 'ECB' }
]);


const paddingOptions = ref<SelectProps['options']>([
    { value: 'Pkcs7', label: 'Pkcs7' },
    { value: 'Iso97971', label: 'Iso97971' },
    { value: 'AnsiX923', label: 'AnsiX923' },
    { value: 'Iso10126', label: 'Iso10126' },
    { value: 'ZeroPadding', label: 'ZeroPadding' },
    { value: 'NoPadding', label: 'NoPadding' }
]);

const keySizeOptions = ref<SelectProps['options']>([
    { value: '256', label: '256bit' },
    { value: '192', label: '192bit' },
    { value: '128', label: '128bit' }
]);


const labelCol = { span: 4 };
const wrapperCol = { span: 14 };
const data = reactive(['Encrypt', 'Decrypt']);
const modelRef = reactive({
    base64Input: 'Hello World',
    encryptType: data[0],
    passphrase: '123456',
    mode: 'CBC',
    padding: 'Pkcs7',
    keySize: '256'
});



const base64Output = computed(() => {
    // var key = "iklEzwhieW1S4VyKk1GJMrhs5fl4ybAS";
    // // var iv = "0000000000000000"
    
    // var iv = forge.util.createBuffer();
    // for (let i = 0; i<16; i++) {
    //     iv.putInt32(0)
    // }
   
    // /* alternatively, generate a password-based 16-byte key
    // var salt = forge.random.getBytesSync(128);
    // var key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);
    // */
    // // encrypt some bytes using CBC mode
    // // (other modes include: ECB, CFB, OFB, CTR, and GCM)
    // // Note: CBC and ECB modes use PKCS#7 padding as default
    // var cipher = forge.cipher.createCipher('AES-CBC', key);
    // cipher.start({ iv: iv });
    // cipher.update(forge.util.createBuffer(forge.util.encodeUtf8("Hello World")));
    // cipher.finish();
    // var encrypted = cipher.output;
    // // outputs encrypted hex
    // console.log(forge.util.encode64(encrypted.data));
    // console.log(cipher);
    // var decipher = forge.cipher.createDecipher('AES-CBC', key);
    // decipher.start({ iv: iv });
    // decipher.update(encrypted);
    // var result = decipher.finish(); // check 'result' for true/false
    // // outputs decrypted hex
    // console.log(decipher.output.data);
    if (modelRef.encryptType == "Encrypt") {
        const encrypted = CryptoES.AES.encrypt(modelRef.base64Input, modelRef.passphrase, {
            mode: CryptoES.mode[modelRef.mode],
            padding: CryptoES.pad[modelRef.padding]
        });
        return encrypted.toString();
    } else {
        const decrypted = CryptoES.AES.decrypt(modelRef.base64Input, modelRef.passphrase, {
            mode: CryptoES.mode[modelRef.mode],
            padding: CryptoES.pad[modelRef.padding]
        });
        return decrypted.toString(CryptoES.enc.Utf8)
    }
})
const { resetFields, validate, validateInfos } = useForm(
    modelRef,
    reactive({
        base64Input: [
            {
                required: true,
                message: 'Please input Base64 encoding',
            },
        ]
    }),
);
</script>